/*
 *	Source: http://www.yolinux.com/TUTORIALS/XML-Xerces-C.html
 */

#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <list>


#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

#include "XMLParser.h"


using namespace xercesc;
using namespace std;




/*
 * Constructor
 * Initialize Xerces infrastructure
 * throw exception here to return ERROR_XERCES_INIT
 * Tags and attributes used in XML file.
 * Can't call transcode till after Xerces Initialize()
 *
 */
XMLParser::XMLParser()
{
	XMLParser_Init();
}


/*
 * Constructor
 * Initialize Xerces infrastructure
 * @param char* strRoot - Root Element
 * @param char* strAppSettings - 1st Element
 *
 */
XMLParser::XMLParser(char* strRoot, char* strAppSettings)
{
	XMLParser_Init();
	m_TAG_root = XMLString::transcode(strRoot);
	m_TAG_ApplicationSettings = XMLString::transcode(strAppSettings);
	m_TAG_ApplicationSettings2 = XMLString::transcode("");
}


/*
 * Constructor
 * Initialize Xerces infrastructure
 * @param char* strRoot - Root Element
 * @param char* strAppSettings - 1st Element
 * @param char* strAppSettings2 - 2nd Element
 *
 */
XMLParser::XMLParser(char* strRoot, char* strAppSettings, char* strAppSettings2)
{
	XMLParser_Init();
	m_TAG_root = XMLString::transcode(strRoot);
	m_TAG_ApplicationSettings = XMLString::transcode(strAppSettings);
	m_TAG_ApplicationSettings2 = XMLString::transcode(strAppSettings2);
}


/**
 * Destructor 
 * Class destructor frees memory used to hold the XML tag and 
 *  attribute definitions. It als terminates use of the xerces-C
 *  framework.
 *
 * Free memory
 * Terminate Xerces
 * Terminate after release of memory
 */

XMLParser::~XMLParser()
{
	delete m_ConfigFileParser;
	try
	{
		XMLString::release( &m_TAG_root );
		XMLString::release( &m_TAG_ApplicationSettings );
		for (unsigned int i = 0; i < m_ATTR_Options.size(); ++i)
		{
			XMLString::release( &m_ATTR_Options[i] );
		}
	}
	catch( ... )
	{
		cerr << "Unknown exception encountered in TagNamesdtor" << endl;
	}
	try
	{
		XMLPlatformUtils::Terminate();
	}
	catch( xercesc::XMLException& e )
	{
		char* message = xercesc::XMLString::transcode( e.getMessage() );
		cerr << "XML toolkit teardown error: " << message << endl;
		XMLString::release( &message );
	}
}


/**
 *  Function to initialize xerces-C libraries.
 *  The XML tags and attributes which we seek are defined.
 *  The xerces-C DOM parser infrastructure is initialized.
 * @param void
 * @return void
 */
void XMLParser::XMLParser_Init()
{
	try
	{
		XMLPlatformUtils::Initialize();
	}
	catch( XMLException& e )
	{
		char* message = XMLString::transcode( e.getMessage() );
		cerr << "XML toolkit initialization error: " << message << endl;
		XMLString::release( &message );
	}
	m_TAG_root = XMLString::transcode("root");
	m_TAG_ApplicationSettings = XMLString::transcode("ApplicationSettings");
	m_ConfigFileParser = new XercesDOMParser;
	m_ConfigFileParser->setValidationScheme( XercesDOMParser::Val_Always );
	m_ConfigFileParser->setDoNamespaces( false );
	m_ConfigFileParser->setDoSchema( false );
	m_ConfigFileParser->setLoadExternalDTD( false );
	m_ConfigFileParser->setCreateEntityReferenceNodes( true );
}


/**
 * Adds an attribute to be parsed
 * @param char* strOption 
 * @return void
 */
void XMLParser::addATTROption(char* strOption)
{
	XMLCh* ATTR_Option = XMLString::transcode(strOption);
	m_ATTR_Options.push_back(ATTR_Option);
}


/**
 * Checks the presence of the file
 * @param char* fileName
 * @return int - 0 is returned when all is well. -1 if there is an error.
 */
int XMLParser::checkFile(const char* fileName)
{
	struct stat fileStatus;
	int iretStat = 0;
	
	iretStat = stat(fileName, &fileStatus);
	if (iretStat == -1)
	{
		cout << "Error opening configuration file " << fileName << "." << endl;
		return -1;
	}
	return 0;
}




